/* $RCSFile: CrmRatingGrid.ascx.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice/PageModules/CrmRating/CrmRatingGrid.ascx.cs $
 * $log$
 * Revision 20 2010/08/09 10:51:20  christian.surieux
 *   Added Log comment to all .aspx .ascx .master files
 * Revision 19 2010/08/09 09:43:51  christian.surieux
 *   Added Log to cs sources files
 * Revision 6 2010/08/06 19:56:25  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Globalization;

using AddonNice.Core;
using AddonNice.UI;
using AddonNice.UI.WebControls;
using AddonNice.UI.DataTypes;
using AddonNice.Configuration;
using AddonNice.Settings;
using AddonNice.Diagnostics;
using AddonNice.Helpers;
using AddonNice.Configuration.Settings;
using AddonNice.Settings.PageModules.Announcements;
using AddonNice.Settings.PageModules.CrmRating;
using AddonNice.CRMWrapper;

using Telerik.Web.UI;

using Trace2    =   System.Diagnostics.Trace;

namespace AddonNice.PageModules.CrmRating
{
    public class CrmRatingGridSI : CrmRatingBaseSI
    {
        public CrmRatingGridSI(ModuleSettingsDictionary bSettings,ISettingsOwner pm)
            : base()
        {
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]CrmRatingGridSI Ctor BEG.",RatingTrace.Sw.Info);
            InitSettings(bSettings,pm);
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]CrmRatingGridSI Ctor END.",RatingTrace.Sw.Info);
        }

        public override void InitSettings(ModuleSettingsDictionary bSettings,ISettingsOwner pm)
        {
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]CrmRatingGridSI InitSettings BEG.",RatingTrace.Sw.Info);
            base.InitSettings(bSettings,pm);
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]CrmRatingGridSI InitSettings END.",RatingTrace.Sw.Info);
        }
    }

            
    /// <summary>
    /// Input Ratings from a grid
    /// </summary>
    public partial class CrmRatingGrid : PortalCRMModuleControl 
    {
		RatingDB CrmRatingDB      =   new RatingDB();

        RatingContext _RContext     =   null;
        
        protected RatingContext RContext
        {
            get
            {
                if ( _RContext == null )
                {
                    _RContext       =   new RatingContext(Request,Wrapper,Settings,ResetWrapper);
                    if ( IsTrackingViewState )
                        ( (IStateManager)_RContext ).TrackViewState();
                }
                return _RContext;
            }
        }


		SortedList<int,bool> AlreadyRated
		{
			get
			{
				if (Object.Equals(Session["AlreadyRated"], null))
				{
					SortedList<int,bool> lst    =   new SortedList<int,bool>();
					Session["AlreadyRated"]     =   lst;
                    return lst;
				}
				return (SortedList<int,bool>)Session["AlreadyRated"];
			}
			set
			{
				Session["AlreadyRated"]         =   value;
			}
		}

		#region General Implementation

        public override bool NeedAttachedEntity
        {
            get
            {
                return false;
            }
        }

		public override Guid GuidID 
		{
			get
			{
				return new Guid("{CB230AD6-573E-487a-BC3E-C14B96EDBD7B}");
			}
		}

		#endregion

        /// <summary>
        /// Public constructor. Sets base settings for module.
        /// </summary>
        public CrmRatingGrid() 
        {
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]CrmRatingGrid Ctor Called.",RatingTrace.Sw.Info);
        }

        public override string ExtendedResourcesGroup 
		{
            get
            {
                const string extgrp                     =   "CRMRATING";
                return extgrp;
            }
		}

        public override void InitPortalModuleControl(ModuleSettingsDictionary bSettings)
        {
            PortalModuleInitializer =   new CrmRatingGridSI(bSettings,this);
        }


        /// <summary>
        /// The Page_Load event handler on this User Control is used to
        /// obtain a DataSet of announcement information from the CrmRating
        /// table, and then databind the results to a templated DataList
        /// server control.  It uses the AddonNice.CrmRatingDB()
        /// data component to encapsulate all data functionality. 
        /// </summary>
        protected void Page_Load(object sender, System.EventArgs e) 
        {
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid Page_Load Time: {0}, IsPostBack: {1}",DateTime.UtcNow,IsPostBack),RatingTrace.Sw.Info);
            if ( !IsPostBack )
            {
			    SqlDataReader dr                =   null;
		        RContext.RatingEntityName       =   string.Empty;
			    try
			    {
				    dr                          =   CrmRatingDB.GetRatingGlobalized(ModuleID);

				    // Load first row into DataReader
				    if (dr.Read())
				    {
					    RContext.TitleRating    =   (string)dr["Title"];
                        RContext.StarNumber     =   (int)dr["StarNumber"];
                        RContext.ItemCount      =   (int)dr["ItemCount"];
					    RContext.RatingEntityName        =   (string)dr["CrmEntityName"];
                        //CreatedDate.Text      =   ((DateTime)dr["CreatedDate"]).ToShortDateString();
                        RContext.RatingExist             =   true;
				    }
			    }
			    catch (Exception ex)
			    {
				    if (RatingTrace.Sw.TraceError)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmRatingGrid Page_Load ex: {0}", ex),RatingTrace.Sw.Info);
				    throw;
			    }
			    finally
			    {
				    if (dr != null)
					    dr.Close();
			    }
            }
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("CrmRatingGrid Page_Load END.",RatingTrace.Sw.Info);
        }

		public DataTable GetDataTable()
		{
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid GetDataTable BEG.",RatingTrace.Sw.Info);
			DataTable tb                    =   null;
			try
			{
				tb                          =   CrmRatingDB.GetRatingDetailsGlobalized(ModuleID);
				// Only way to avoid double session rating
                tb.Columns.Add(new DataColumn("isRated"));
                SortedList<int,bool> rt     =   AlreadyRated;
				for (int i = 0; i < tb.Rows.Count; i++)
				{
                    DataRow rw              =   tb.Rows[i];
                    int RatingItemId        =   (int)rw["ItemID"];
                    if ( rt.ContainsKey(RatingItemId) )
					        rw["isRated"]   =   true;
				    else    rw["isRated"]   =   false;
				}
			}
			catch (Exception ex)
			{
				if (RatingTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmRatingGrid GetDataTable ex: {0}", ex),RatingTrace.Sw.Info);
				throw;
			}
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid GetDataTable END Count: {0}.",tb.Rows.Count),RatingTrace.Sw.Info);
			return tb;
		}

		protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
		{
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid RadGrid1_NeedDataSource BEG Reason: {0}.",e.RebindReason),RatingTrace.Sw.Info);
			RadGrid1.DataSource     =   GetDataTable();
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid RadGrid1_NeedDataSource END .",RatingTrace.Sw.Info);
		}

		protected void RadRating1_Rate(object sender, EventArgs e)
		{
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid RadRating1_Rate BEG.",RatingTrace.Sw.Info);
			RadRating oRating       =   (RadRating)sender;
			GridDataItem dataItem   =   (GridDataItem)oRating.Parent.Parent;
            SqlDataReader dr        =   null;
			try
			{
                int RatingItemID                =   RContext.RatingItemID       =   (int)RadGrid1.MasterTableView.DataKeyValues[dataItem.ItemIndex]["ItemID"];
                dr                              =   CrmRatingDB.GetSingleRatingDetailGlobalized(RatingItemID);
                dr.Read();
                object ob                       =   dr["CrmID"];
                if ( ob != null && !(ob is DBNull ))
                    RContext.RatingCrmDetailID  =   (Guid)ob;
                ob                              =   dr["CrmEntityID"];
                if ( ob != null && !(ob is DBNull ))
                    RContext.RatingCrmEntityID  =   (Guid)ob;
				RContext.TitleRatingDetail      =   (string)dr["Title"];
                int currentNumberRatings        =   (int)RadGrid1.MasterTableView.DataKeyValues[dataItem.ItemIndex]["TimesRated"];
                //get the current Rating from the DataTable
                double currentRating            =   (double)RadGrid1.MasterTableView.DataKeyValues[dataItem.ItemIndex]["AverageRating"];
				currentNumberRatings++;

			    if (RatingTrace.Sw.TraceVerbose)
                    Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid RadRating1_Rate oRating.Value: {0}, RatingItemID: {1}, currentRating: {2}.",
                        oRating.Value,RContext.RatingItemID,currentRating),RatingTrace.Sw.Info);
				//calculate the average rating after the a product has been rated
				//double ratedAverageValue    = (oRating.Value + currentRating * (currentNumberRatings-1)) / currentNumberRatings;//Math.Round(, 1);
                
                AlreadyRated[RContext.RatingItemID]  =   true;
                dr.Close();
            	oRating.Value               =   RContext.Rate(oRating,UserLogged);
			}
			catch (Exception ex)
			{
				if (RatingTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmRatingGrid RadRating1_Rate ex: {0}", ex),RatingTrace.Sw.Info);
				RadGrid1.Controls.Add(new LiteralControl("Unable to update Ratings. Reason: " + ex.Message));
			}
            finally
            {
                if ( dr != null )
                    dr.Close();
            }
			oRating.ReadOnly                =   true;
			RadGrid1.Rebind();
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid RadRating1_Rate END.",RatingTrace.Sw.Info);
		}

        protected void ConfigureRating(RadRating RadRating1)
        {
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid ConfigureRating BEG.",RatingTrace.Sw.Info);
            RadRating1.ItemCount            =   Settings[RStr.NumberStars].ToInt();
            RadRating1.SelectionMode        =   (RatingSelectionMode)Enum.Parse(typeof(RatingSelectionMode),Settings[RStr.SelectionMode].Value);
            RadRating1.IsDirectionReversed  =   Settings[RStr.IsDirectionReversed].ToBool();
            RadRating1.Precision            =   (RatingPrecision)Enum.Parse(typeof(RatingPrecision),Settings[RStr.Precision].Value);
            RadRating1.Orientation          =   (Orientation)Enum.Parse(typeof(Orientation),Settings[RStr.Orientation].Value);
            RadRating1.AutoPostBack         =   true;
            RadRating1.Rate                 +=  new EventHandler(RadRating1_Rate);
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid ConfigureRating END.",RatingTrace.Sw.Info);
        }

        /// <summary>
        /// Call the edit window
        /// </summary>
        void RadGrid1_UpdateCommand(object source,GridCommandEventArgs e)
        {
            if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid RadGrid1_EditCommand CommandName: {0}", e.CommandName),RatingTrace.Sw.Info);
            int ItemID              =   (int)e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["ItemID"];
            // Go to edit page
            string strUrl           =   HttpUrlBuilder.BuildUrlWithCustomAttributes(Config.ModulesPath + "/CrmRating/CrmRatingEdit.aspx",PageID,string.Format("mID={0}&itemid={1}", ModuleID,ItemID));
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid RadGrid1_EditCommand strUrl: {0}",strUrl),RatingTrace.Sw.Info);
            ADNPage.Redirect(strUrl,true);
        }

        void RadGrid1_DeleteCommand(object source,GridCommandEventArgs e)
        {
		    if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid RadGrid1_DeleteCommand BEG CommandName: {0}",e.CommandName),RatingTrace.Sw.Info);
		    try
		    {
                GridDataItem item = (GridDataItem)e.Item;   
                int ItemID              =   (int)e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["ItemID"];
		        if (RatingTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmRatingGrid RadGrid1_DeleteCommand ItemID: {0}",ItemID),RatingTrace.Sw.Info);
                CrmRatingDB.DeleteRatingDetailGlobalized(ItemID);
		    }
		    catch(Exception ex)
		    {
			    if (RatingTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmRatingGrid RadGrid1_DeleteCommand ex: {0}",ex),RatingTrace.Sw.Info);
                throw;
		    }
		}

        const string BtnUpdateName          =   "UpdateButton";
        void RadGrid1_ItemCreated(object sender,GridItemEventArgs e)
        {
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid RadGrid1_ItemCreated BEG.",RatingTrace.Sw.Info);
            if (e.Item is GridDataItem)  
            {
                GridDataItem gItem          =   e.Item as GridDataItem;
                ImageButton originalButton  =   gItem[BtnUpdateName].Controls[0] as ImageButton;  
                ImageButton newButton       =   new ImageButton();  
                newButton.SkinID            =   "EditBtn"; // StdEdit Btn 
                newButton.CommandArgument   =   originalButton.CommandArgument;  
                newButton.CommandName       =   originalButton.CommandName;  
                newButton.AlternateText     =   originalButton.AlternateText;  
                newButton.ID                =   originalButton.ID;
                gItem[BtnUpdateName].Controls.RemoveAt(0);  
                gItem[BtnUpdateName].Controls.Add(newButton);  
                RadRating RadRating1        =   (RadRating)e.Item.FindControl("RadRating1");
                if ( RadRating1 != null )
                    ConfigureRating(RadRating1);		
            }
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid RadGrid1_ItemCreated END.",RatingTrace.Sw.Info);
        }
        
        protected void RadGrid1_PreRender(object sender, System.EventArgs e)
        {
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid RadGrid1_PreRender BEG.",RatingTrace.Sw.Info);
            bool modif                                      =   false;
            bool showTitleCol                               =   Settings[RStr.ShowTitleCol].ToBool();
            bool showDescCol                                =   Settings[RStr.ShowDescCol].ToBool();
            if ( !IsEditable )
                foreach(GridColumn column in RadGrid1.Columns)
                {
                   if ( (column.UniqueName == "deleteColumn" ) && (column as GridButtonColumn).Visible )
                   {
                        (column as GridButtonColumn).Visible =   false;
                        modif                               =   true;
                   }
                   else if ( (column.UniqueName == "UpdateButton") && (column as GridButtonColumn).Visible )
                   {
                       (column as GridButtonColumn).Visible =   false;
                        modif                               =   true;
                   }
                   else if ( (column.UniqueName == "Title") && !showTitleCol )
                   {
                       (column as GridBoundColumn).Visible =   false;
                        modif                               =   true;
                   }
                   else if ( (column.UniqueName == "Description") && !showDescCol )
                   {
                       (column as GridBoundColumn).Visible =   false;
                        modif                               =   true;
                   }
                }
            if ( modif)
                RadGrid1.Rebind();
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid RadGrid1_PreRender END.",RatingTrace.Sw.Info);
        }
        
        #region IStateManager

        /// <summary>
        /// This member overrides Control.LoadViewState
        /// </summary>
		protected override void LoadViewState(object savedState) 
		{
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmRatingGrid LoadViewState BEG.",RatingTrace.Sw.Info);
			// Customize state management to handle saving state of contained objects.
			if (savedState != null) 
			{
				object[] myState    =   (object[])savedState;

				if (myState[0] != null)
					base.LoadViewState(myState[0]);
				if (myState[1] != null)
					((IStateManager)RContext).LoadViewState(myState[1]);
			}
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmRatingGrid LoadViewState END.",RatingTrace.Sw.Info);
		}
        
        /// <summary>
        /// This member overrides Control.SaveViewState
        /// </summary>
		protected override object SaveViewState() 
		{
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmRatingGrid SaveViewState BEG.",RatingTrace.Sw.Info);
			// Customized state management to handle saving state of contained objects  such as styles.
			object baseState                =   base.SaveViewState();
			object RatingTableStyleState    =   (_RContext != null) ? ((IStateManager)_RContext).SaveViewState() : null;

			object[] myState                =   new object[2];
			myState[0]                      =   baseState;
			myState[1]                      =   RatingTableStyleState;
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmRatingGrid SaveViewState END.",RatingTrace.Sw.Info);
			return myState;
		}

        /// <summary>
        /// This member overrides Control.TrackViewState.
        /// </summary>
		protected override void TrackViewState() 
		{
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmRatingGrid TrackViewState BEG.",RatingTrace.Sw.Info);
			// Customized state management to handle saving state of contained objects such as styles.
			base.TrackViewState();

			if (_RContext!= null)
				((IStateManager)_RContext).TrackViewState();
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmRatingGrid TrackViewState END.",RatingTrace.Sw.Info);
		}

        #endregion IStateManager 
        
        #region Std Overrides

        public override void Page_PreInit(object sender, EventArgs e)
        {
			if (RatingTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid Page_PreInit BEG.",(RatingTrace.Sw.TraceVerbose) ? RatingTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
            AddText    =   "CRMRATING_ADD";
            AddUrl     =   Config.ModulesPath + "/CrmRating/CrmRatingEdit.aspx";
            base.Page_PreInit(sender, e);
			if (RatingTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine("[V]CrmRatingGrid Page_PreInit END.",(RatingTrace.Sw.TraceVerbose) ? RatingTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
        }

        override protected void OnInit(EventArgs e)
		{
            // Avoid any inputComment
            RContext.IsGridRating               =   true;
			InitializeComponent();
			base.OnInit(e);
		}

        private void InitializeComponent() 
        {
			Load                        +=  new EventHandler(Page_Load);
            RadGrid1.NeedDataSource     +=  new GridNeedDataSourceEventHandler(RadGrid1_NeedDataSource);
            RadGrid1.ItemCreated        +=  new GridItemEventHandler(RadGrid1_ItemCreated);
            RadGrid1.UpdateCommand      +=  new GridCommandEventHandler(RadGrid1_UpdateCommand);
            RadGrid1.DeleteCommand      +=  new GridCommandEventHandler(RadGrid1_DeleteCommand);
            RadGrid1.PreRender          +=  new EventHandler(RadGrid1_PreRender);
		}

		#endregion
    }
}

